﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Framework.Utility.Extensions
{
    /// <summary>
    /// 数学类扩展方法
    /// </summary>
    public static class MathExtensions
    {

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="type">0:round,1:roundup,2,rounddown</param>
        /// <param name="digits"></param>
        /// <returns></returns>
        public static decimal MathRound(this decimal value, int type, byte digits)
        {
            switch (type)
            {
                //Round
                case 0:
                    return Math.Round(value, digits);
                //Roundup
                case 1:
                    return value.RoundUp(digits);
                //Rounddown
                case 2:
                    return value.RoundDown(digits);
                default:
                    return 0;
            }
        }

        /// <summary>
        /// 远离 0 向上舍入
        /// </summary>
        public static decimal RoundUp(this decimal value, byte digits)
        {
            if (digits == 0)
            {
                return (value >= 0 ? decimal.Ceiling(value) : decimal.Floor(value));
            }

            decimal multiple = Convert.ToDecimal(Math.Pow(10, digits));
            return (value >= 0 ? decimal.Ceiling(value * multiple) : decimal.Floor(value * multiple)) / multiple;
        }

        /// <summary>
        /// 靠近 0 向下舍入
        /// </summary>
        public static decimal RoundDown(this decimal value, byte digits)
        {
            if (digits == 0)
            {
                return (value >= 0 ? decimal.Floor(value) : decimal.Ceiling(value));
            }

            decimal multiple = Convert.ToDecimal(Math.Pow(10, digits));
            return (value >= 0 ? decimal.Floor(value * multiple) : decimal.Ceiling(value * multiple)) / multiple;
        }

        /// <summary>
        /// 四舍五入
        /// </summary>
        public static decimal RoundEx(this decimal value, byte digits)
        {
            if (digits >= 0)
            {
                return decimal.Round(value, digits, MidpointRounding.AwayFromZero);
            }

            decimal multiple = Convert.ToDecimal(Math.Pow(10, -digits));
            return decimal.Round(value / multiple, MidpointRounding.AwayFromZero) * multiple;
        }

        /// <summary>
        /// 远离 0 向上舍入
        /// </summary>
        public static double RoundUp(this double value, byte digits)
        {
            return decimal.ToDouble(Convert.ToDecimal(value).RoundUp(digits));
        }

        /// <summary>
        /// 靠近 0 向下舍入
        /// </summary>
        public static double RoundDown(this double value, byte digits)
        {
            return decimal.ToDouble(Convert.ToDecimal(value).RoundDown(digits));
        }

        /// <summary>
        /// 四舍五入
        /// </summary>
        public static double RoundEx(this double value, byte digits)
        {
            return decimal.ToDouble(Convert.ToDecimal(value).RoundEx(digits));
        }
    }
}
